using System;
using System.Collections.Generic;
using Clandestine.Base;
using Clandestine.Engines.Field;
using System.Drawing;
using Qyoto;

namespace Shlick
{
	public class TilesMenu : QObject, IContextMenu
	{
		public MapDocument MapDocument { get; private set; }
		private QMenu menu;
		private Layer layer;
		private Rectangle selectedRegion;
		private Tile?[,] tiles;
		
		private static Dictionary<MapDocument, Tile?[,]> clipboard = new Dictionary<MapDocument, System.Nullable<Tile>[,]>();
		
		public TilesMenu(MapDocument mapDocument, Layer layer, Rectangle selectedTiles)
		{
			menu = new QMenu();
			menu.AddAction(new QIcon(":/tango/scalable/actions/edit-redo.svg"), "Move Tiles", this, SLOT("onMoveTiles()"));
			menu.AddSeparator();
			menu.AddAction(new QIcon(":/tango/scalable/actions/edit-cut.svg"), "Cut Tiles", this, SLOT("onCutTiles()"));
			menu.AddAction(new QIcon(":/tango/scalable/actions/edit-copy.svg"), "Copy Tiles", this, SLOT("onCopyTiles()"));
			menu.AddAction(new QIcon(":/tango/scalable/actions/edit-paste.svg"), "Paste Tiles", this, SLOT("onPasteTiles()"));
			menu.AddSeparator();
			menu.AddAction(new QIcon(":/tango/scalable/actions/edit-delete.svg"), "Erase Tiles", this, SLOT("onEraseTiles()"));
			menu.AddSeparator();
			menu.AddAction(new QIcon(":/tango/scalable/actions/go-jump.svg"), "Promote to Object", this, SLOT("onPromote()"));
			
			this.MapDocument = mapDocument;
			this.layer = layer;
			this.selectedRegion = selectedTiles;
			this.tiles = extractTiles(layer, selectedTiles);
		}
		
		private Tile?[,] extractTiles(Layer layer, Rectangle st)
		{
			Tile?[,] tiles = new Tile?[st.Width + 1, st.Height + 1];
			
			for (int y = st.Y; y <= st.Y + st.Height; y++)
				for (int x = st.X; x <= st.X + st.Width; x++)
					tiles[x - st.X, y - st.Y] = layer.GetTile(x, y);
			
			return tiles;
		}
		
		public void Show()
		{
			menu.Exec(QCursor.Pos());
		}
		
		[Q_SLOT("onMoveTiles()")]
		private void onMoveTiles()
		{
			// Do cut & activate paste tool in one operation, leaving clipboard alone.
			onEraseTiles();
			this.MapDocument.ToolManager.OpenNewTool(ToolTypes.TilePaster, tiles);
		}
		
		[Q_SLOT("onCutTiles()")]
		private void onCutTiles()
		{
			// Cut: Erase tiles from layer, and store on clipboard.
			onCopyTiles();
			onEraseTiles();
		}
		
		[Q_SLOT("onCopyTiles()")]
		private void onCopyTiles()
		{
			// Copy: Store tiles on clipboard, leaving existing application on layer.
			if (clipboard.ContainsKey(MapDocument))
				clipboard.Remove(MapDocument);
			clipboard.Add(MapDocument, tiles);
		}
		
		[Q_SLOT("onPasteTiles()")]
		private void onPasteTiles()
		{
			// Paste: Activate paste tool - like the tile painter, but from the clipboard, not the tileset.
			// (A different tool is required, as the tile painter can only handle one contiguous selection from one tileset.)
			if (!clipboard.ContainsKey(MapDocument))
				new QMessageBox(QMessageBox.Icon.Information, "Clipboard Empty", "No tiles have been cut or copied.\n(Note you can only paste on to the same map atm.)").Show();
			else
			{
				Tile?[,] t = clipboard[MapDocument];
				this.MapDocument.ToolManager.OpenNewTool(ToolTypes.TilePaster, t);
			}
		}
		
		[Q_SLOT("onEraseTiles()")]
		private void onEraseTiles()
		{
			// Erase tiles from layer.
			PaintTilesCommand.EraseTiles(this.layer, this.selectedRegion).Do();
		}
		
		[Q_SLOT("onPromote()")]
		private void onPromote()
		{
			// Display message telling Mikey if he wants to use this feature then he should write it.
			new QMessageBox(QMessageBox.Icon.Warning, "Command Unavailable", "Sorry, people called Mikey have to write this feature before it can be used.").Show();
		}
	}
}

